home *** CD-ROM | disk | FTP | other *** search
- /**
- * FieldType constants for the database type currently supported by Fusion for internal tables
- */
-
- function NOF_DataObjects_FieldType(){
- }
-
- NOF_DataObjects_FieldType.prototype.VARCHAR = 0;
- NOF_DataObjects_FieldType.prototype.INTEGER = 1;
- NOF_DataObjects_FieldType.prototype.BYTES_LIST = 2;
- NOF_DataObjects_FieldType.prototype.IMAGE_PATH = 3;
- NOF_DataObjects_FieldType.prototype.LARGE_TEXT = 4;
- NOF_DataObjects_FieldType.prototype.DATE = 5; //TODO: determine the actual value for DATETIME. it's treated as LONG
- NOF_DataObjects_FieldType.prototype.REAL = 6;
- NOF_DataObjects_FieldType.prototype.INTERNAL_PAGE_LINK = 7;
-
-
- /**
- * FieldInfo class constructor
- * @param name field name
- * @param type field type as permitted by FieldType
- * @param [position] to be used when the physical order fields get created matters
- */
- function NOF_DataObjects_FieldInfo(name, type, position){
- this.name = name;
- this.type = type;
- this.position = position;
- }
-
- /**
- * FieldValue class constructor
- * @param name field name
- * @param value field value
- */
- function NOF_DataObjects_FieldValue( name, value){
- this.name = name;
- this.value = value;
- }
-
- /**
- * Table class constructor
- * @param type the table type. currently is computed as a BaseId + StoreId
- * @param name the table name
- * @param [pkName] the primary key if any. these are autoincremented and cannot be set
- */
- function NOF_DataObjects_Table( type, name, pkName){
- this.__proto__ = NOF_DataObjects_Table.prototype;
-
- if (arguments.length > 0){ //not a default contructor call
- this.type = type;
- this.name = name;
- this.pkName = pkName;
- this.fisSelection = null;
- }
- }
-
- function NOF_DataObjects_Table_ProtoBuilder(){
- var NOF_DataObjects_Table_Sequences = new Array();
- var NOF_DataObjects_Table_SelectionsList = new Array();
- var NOF_DataObjects_Table_LoadedTables = new Array();
-
- var method = NOF_DataObjects_Table.prototype;
-
- //these are *NOT* static as long as you access them via classInstance.propertyName
- method.type = null;
- method.name = null;
- method.pkName = null;
- method.fisSelection = null;
- method.instanceId = -1;
-
- /**
- * getNextSequence
-
- * @return the next sequence value for the primary key
- */
- method.getNextSequence = function getNextSequence(){
- //the starting value is set in getTable();
- //NOF.Contract.Assert( NOF_DataObjects_Table_Sequences[ this.getFullTableName() ] != null, "Sequence not initialized for " + this.getFullTableName());
- return ++NOF_DataObjects_Table_Sequences[ this.getFullTableName() ];
- };
-
- method._setSequence = function _setSequence( seq ){
- NOF_DataObjects_Table_Sequences[ this.getFullTableName() ] = seq;
- };
-
- /**
- * insert inserts a new row
- * @param fields array of FieldInfo objects
-
- * @return pkValue the pkValue for inserted if the table has one or -1 otherwise
- */
- method.insert = function insert( fields ){
- //create new record
- var selHnd = this.getSelectionHandle();
- selHnd.NewRecord();
-
- //generate a PK if necessary
- var pkValue = -1
- if ( this.pkName != null ){
- pkValue = this.getNextSequence();
- selHnd.SetField(this.pkName, pkValue);
- }
-
- //set values for each field
- for (var i=0; i < fields.length; i++){
- NOF.Contract.Require( fields[i].name != this.pkName, "You cannot specifiy a value for autogenerated keys! " +this.pkName);
- selHnd.SetField( fields[i].name, (fields[i].value != null) ? fields[i].value : "" );
- }
-
- //update the record
- selHnd.Update();
-
- return pkValue;
- };
-
- /**
- * create creates a FSITable and the associated FSISelection
- * @param instanceId the table type
-
- * @return selHnd the associated FSISelection handle
- */
- method.create = function create( instanceId ){
- NOF.Contract.Require( this.name != null && this.name.length > 0, "Name has to be defined!");
-
- var qualifiedTableName = this.getFullTableName( instanceId );
- var selHnd = this._GetSelectionHandle( qualifiedTableName );
- if ( selHnd == null ){
- var fsiApp = NOF.App.getFSIApp();
- //var table = fsiApp.NewTable( this.name, this.type);
- var table = fsiApp.NewTable( qualifiedTableName, this.type);
-
- NOF.Contract.Assert( table != null, "Database inconsistency! Table already exists when it should not");
- var fieldsList = this.getDDL();
- for (var i=0; i < fieldsList.length; i++){
- table.AddField( fieldsList[i].name, fieldsList[i].type );
- }
-
- selHnd = fsiApp.NewSelection( qualifiedTableName, this.type );
- selHnd.SetTable( table );
- }
-
- return selHnd;
- };
-
- /**
- * getRecordsCount
-
- * @return the records count
- */
- method.getRecordsCount = function getRecordsCount(){
- return this.getSelectionHandle().Count();
- };
-
- method.getTableName = function getTableName(){
- return this.name;
- };
-
- /**
- * getFullTableName
- * @param [instanceId] the table instance number
-
- * @return the full name as name + type in case type is defined.
- */
- method.getFullTableName = function getFullTableName( instanceId ){
- var typeStr = (instanceId != null ? instanceId : 0);
- typeStr = (typeStr!= null ? "_" + typeStr : "");
- return this.name + typeStr;
- };
-
- /**
- * getTable initialises the table by loading the associated FSISelection,<br>
- * setting the sequence value if it has a primary key
- * @param instanceId the table instance number
-
- * @return the Table instance associated w/ the requested <code>type</code>
- */
- method.getTable = function getTable( instanceId ){
- //check in the cache. load it if not accessed yet.
- var tableId = this.getFullTableName ( instanceId );
- if ( NOF_DataObjects_Table_LoadedTables[tableId] == null ){
- var selHnd = this._GetSelectionHandle( instanceId );
- if ( selHnd == null )//table not created yet. go ahead and create it
- selHnd = this.create( instanceId );
-
- var table = new this.__constructor__();
- table.setSelectionHandle( selHnd );
- table.instanceId = instanceId;
-
- NOF_DataObjects_Table_LoadedTables[tableId] = table;
-
- if ( this.pkName != null ){//table has a primary key
- if ( selHnd.Count() > 0){
- selHnd.SetIndex( selHnd.Count() - 1 ); //move it to the last position. might be safer to compute the maximum instead of relying on ordered rows!
- var curSeq = 0 + selHnd.GetField( this.pkName );
- table._setSequence( curSeq++ );
- }else{
- table._setSequence( 0 );
- }
- }
- }
-
- return NOF_DataObjects_Table_LoadedTables[tableId];
- };
-
- /**
- * getDDL - abstract method. subclasses needs to provide the concrete DDL for the specific table they implement.
- * <br>DDL is an array of FieldsInfo objects
- */
- method.getDDL = function getDDL(){
- throw new NOF.UTIL.AbstractMethodError( "Table.getDDL is an abstract method!");
- };
-
- //various class member accessors
- method.getSelectionHandle = function getSelectionHandle(){return this.fisSelection;};
- method.setSelectionHandle = function setSelectionHandle( hnd ){
- this.fisSelection = hnd;
- };
-
- method.getType = function getType(){return this.type;};
- method.getName = function getName(){return this.name;};
- method.getPkName = function getName(){return this.pkName;};
-
- /**
- * selectAll fetches all table records
- *
- * @return resultSet an array of arrays of FieldValue objects. it is NEVER null.
- */
- method.selectAll = function selectAll(){
- return this.selectByFields();
- };
-
- /**
- * selectByFields
- * @param fields an array of FieldValue object. can be empty and will match all the records
- * @return resultSet an array of arrays of FieldValue objects. it is NEVER null.
- */
- method.selectByFields = function selectByFields( fields ){
- var resultSet = new Array();
- var tableDDL = this.getDDL();
- var selHnd = this.getSelectionHandle();
- var str = "";
- if (fields == null)
- str = "ALL";
-
- function _selectVisitor(){
- var record = new Array();
-
- for (var i=0; i < tableDDL.length; i++)
- record.add( new NOF_DataObjects_FieldValue( tableDDL[i].name, "" + selHnd.GetField(tableDDL[i].name) ) );
-
- resultSet.add( record );
- }
-
- this.VisitRowsByFields(fields, _selectVisitor);
- return resultSet;
- };
-
- /**
- * selectByIndex reads the record at the specified index
- * @param index a valid positive numeric value
- */
- method.selectByIndex = function selectByIndex( index ){
- if ( this.moveTo( index ) ){
- var selHnd = this.getSelectionHandle();
- var tableDDL = this.getDDL();
-
- var record = new Array();
- for (var i=0; i < tableDDL.length; i++)
- record.add( new NOF_DataObjects_FieldValue( tableDDL[i].name, "" + selHnd.GetField(tableDDL[i].name) ) );
-
- return record;
- }else{
- return null;
- }
- };
-
- /**
- * VisitRowsByFields iterates over the records list and invokes the callback method w/ the field index<br>
-
- * @param fields an array of FieldValue objects. can be empty and will match all the record
- * @param visitorCB a function referenced that will be invoked everytime a match is found
- */
- method.VisitRowsByFields = function VisitRowsByField( fields, visitorCB ){
- NOF.Contract.Require( visitorCB != null && typeof (visitorCB) == 'function', "Second argument needs to be a valid function pointer!");
-
- var recCount = this.getRecordsCount();
- if (recCount > 0){
- var selHnd = this.getSelectionHandle();
- selHnd.SetIndex(0); //make sure we start from the begining
- var isSearchByPK = false;
- if (fields != null) {
- for (var i=0; i<fields.length;i++){//determine whether pk is a condition to stop after first match
- if ( fields[i].name == this.pkName ){
- isSearchByPK = true;
- break;
- }
- }
- }
-
- for ( var i=0; i < recCount; i++ ){
- if ( fields == null){//call back uncoditionally
- visitorCB( i );
- }else{
- var matches = true;
- for (var j=0; j < fields.length; j++){
- if ( selHnd.GetField( fields[j].name ) != fields[j].value ){
- matches = false;
- break;
- }
- }
-
- if ( matches ){
- visitorCB( i );
- if ( isSearchByPK ) //the search should end here if we're looking for the primaryKey
- break;
- }
-
- }
- selHnd.NextRecord();
- }
- }
- };
-
- /**
- * updateByFields updates the matching field(s) w/ the new values
- * @param fields an array of FieldValue objects.
- * @param newRowValue a valid array of FieldValues objects
-
- * @return count the number of rows that were updated
- */
- method.updateByFields = function updateByFields(fields, newRowValue){
- NOF.Contract.Require( fields != null, "Where clause (first argument ) cannot be empty!");
- NOF.Contract.Require( newRowValue != null && newRowValue.length != null && newRowValue.length > 0, "Set clause (second arg) cannot be empty!");
-
- var count = 0;
- var selHnd = this.getSelectionHandle();
-
- function _updateVisitor(){
- for (var i=0; i < newRowValue.length; i++)
- selHnd.SetField( newRowValue[i].name, (newRowValue[i].value != null) ? newRowValue[i].value : "");
-
- selHnd.Update();
- count++;
- }
-
- this.VisitRowsByFields( fields, _updateVisitor);
-
- return count;
- };
-
- /**
- * updateByIndex updates the record referenced <code>index</code>
- * @param index a valid positive numeric value
- * @param newRowValue a valid array of FieldValues objects
- */
- method.updateByIndex = function updateByIndex( index, newRowValue ){
- if ( this.moveTo( index ) ){
- var selHnd = this.getSelectionHandle();
- for (var i=0; i < newRowValue.length; i++)
- selHnd.SetField( newRowValue[i].name, (newRowValue[i].value != null) ? newRowValue[i].value : "");
-
- selHnd.Update();
- }
- };
-
- /**
- * deleteAll literally deletes all the records of the table
- * @param [resetSequence] determines wheather the seqenece is reset to 0 or not. default is true;
- *
- */
- method.deleteAll = function deleteAll( resetSequence ){
- resetSequence = (resetSequence != null ? resetSequence : true); //default behaviour is to reset it
- var selHnd = this.getSelectionHandle();
- if (this.getRecordsCount() > 0){
- selHnd.SetIndex(0); //make sure we start from the begining
- while ( this.getRecordsCount() )
- selHnd.DeleteRecord();
- }
-
- NOF.Contract.Ensure( selHnd.Count() == 0, "Record count should be 0 after a delete all!");
- if ( resetSequence )
- this._setSequence( 0 ); //reset the sequence if all rows were deleted
- };
-
- /**
- * deleteByFields deletes all the fields that matches given condition
- * @param fields an array of FieldValue object.
-
- * @return count the number of rows that were deleted
- */
- method.deleteByFields = function deleteByFields( fields ){
- NOF.Contract.Require( fields != null, "Where clause cannot be empty!");
-
- var count = 0;
- var recCount = this.getRecordsCount();
- var isPK = false;
- for (var i=0; i<fields.length;i++) {
- if (fields[i].name == this.pkName) {
- isPK = true;
- break;
- }
- }
- if (recCount > 0){
- var selHnd = this.getSelectionHandle();
- selHnd.SetIndex(0); //make sure we start from the begining
- for ( var i=0; i < recCount; i++ ){
- var matched = true;
- for (var j=0; j<fields.length;j++) {
- if ( selHnd.GetField( fields[j].name ) != fields[j].value ) {
- matched = false;
- break;
- }
- }
- if ( matched ) {
- selHnd.DeleteRecord();
- selHnd.Update();
- recCount--;
- // do not skip record
- i--;
- count++;
-
- if ( isPK ) //the search should end here if we're looking for the primaryKey
- break;
- }else{
- selHnd.NextRecord();
- }
- }
- }
-
- return count;
- };
-
- /**
- * deleteByIndex deletes the record at the specified index
- * @param index a valid positive numeric value
- */
- method.deleteByIndex = function deleteByIndex( index ){
- if ( this.moveTo( index ) ){
- var selHnd = this.getSelectionHandle();
- selHnd.DeleteRecord();
- selHnd.Update();
- }
- };
-
- /**
- * moveTo moves the record pointer to the specified index
- * @param index a valid positive numeric value
-
- * @return count the number of rows that were deleted
- */
- method.moveTo = function moveTo( index ){
- var re = /^[0-9]+$/;NOF.Contract.Require( re.test( index ), "Index has to be a digit value!");
- var recCount = this.getRecordsCount();
- NOF.Contract.Require( index >=0 && index < recCount, "Index out of range!");
-
- if (recCount > 0){
- return this.getSelectionHandle().SetIndex( index );
- }else{
- return false;
- }
- };
-
- /**
- * _GetSelectionHandle
- * @param instanceId the table instance number
-
- * @return selHnd the FSISelection object associated with the given table
- */
- method._GetSelectionHandle = function _GetSelectionHandle( instanceId ){
- return this._GetSelectionByName( this.getFullTableName( instanceId ) );
- };
-
- /**
- * _GetSelectionByName looks up the selections list by name
- * @param name the FSISelection name
-
- * @return selHnd the FSISelection object associated with <code>name</name>
- */
- method._GetSelectionByName = function _GetSelectionByName( name ){
- if ( NOF_DataObjects_Table_SelectionsList[ name ] == null ){
- var fsiApp = NOF.App.getFSIApp();
- var selections = fsiApp.GetAllSelectionsByName( name );
-
- var count = selections.Count();
- NOF.Contract.Assert( count <=1, "Selection name has to be unique!");
- if ( count == 1)
- NOF_DataObjects_Table_SelectionsList[ name ] = selections.GetNext();
- }
-
- return NOF_DataObjects_Table_SelectionsList[ name ];
- };
-
- method.DEBUG = function DEBUG(caller, level){
- var selHnd = this.getSelectionHandle();
- //NOF.SysOut.info("[" + caller + "] " + "tName=" + this.name + " sName=" + selHnd.Name + " rowCount" + selHnd.Count());
- }
-
- method.release = function release(){
- this.fisSelection = null;
- }
-
- method.clearCache = function clearCache(){
- //debugger;
- var arr = NOF_DataObjects_Table_LoadedTables;
- for ( var item in arr)
- if ( typeof( arr[item] ) != 'function' ){
- //NOF.SysOut.info("releasing table: " + item);
- arr[item].release();
- arr[item] = null;
- }
-
- arr = null;
- NOF_DataObjects_Table_LoadedTables = null;
-
- arr = NOF_DataObjects_Table_SelectionsList;
- for ( var item in arr)
- if ( typeof( arr[item] ) != 'function' )
- arr[item] = null;
-
- arr = null;
- NOF_DataObjects_Table_SelectionsList = null;
- }
-
- method.super_clearCache = method.clearCache;
- }
-
- NOF_DataObjects_Table_ProtoBuilder();
-
- /**
- * DataObjects namespace
- */
- function NOF_DataObjects(){
- this.__proto__ = NOF_DataObjects.prototype;
-
- this.Table = NOF_DataObjects_Table;
- this.FieldInfo = NOF_DataObjects_FieldInfo;
- this.FieldValue = NOF_DataObjects_FieldValue;
- this.FieldType = new NOF_DataObjects_FieldType;
- }
-
- NOF.__proto__.DO = new NOF_DataObjects();